import { ResParamInterface, ReqParamInterface } from "../lib/interface";
import { PROTOCOL_NAME } from "../lib/constant";

export interface OptionsInterface { 
    url: string;
    // protocols?: string[]
}

class WepyApi {
    private __ids__: any;
    private __eventKey__: string = '__api__';
    private protocol: string = PROTOCOL_NAME;

    constructor(public wepy: any, public options: OptionsInterface) {
        let self = this;
        self.__ids__ = {};
    }

    async init() { 
        let self = this;
        return new Promise((resolve, reject) => { 
            self.wepy.onSocketMessage((msg: { data: ResParamInterface }) => {
                let data = msg.data;
                if (typeof data == 'string') { 
                    data = JSON.parse(data);
                }
                if (data.__eventKey__ == this.__eventKey__) {
                    self.handle(data);
                }
            });
            self.wepy.onSocketOpen(() => { 
                return resolve(true);
            })
            self.wepy.onSocketError((err: Error) => { 
                reject(err);
            })
            self.wepy.connectSocket({
                url: self.options.url,
                protocols: [self.protocol]
            })
        })

    }

    handle(resData: ResParamInterface) {
        let id = resData.__id__;
        let fn = this.__ids__[id];
        delete this.__ids__[id];
        if (fn && typeof fn == 'function') {
            if (resData.code) {
                return fn(new Error(resData.msg as string));
            }
            return fn(null, resData.data);
        }
        console.warn(`ignore API.handle not found cb id:`, resData);
    }

    async fetch(url: string, data: any, options: any) {
        let self = this;
        let id = Date.now() + '' + Math.ceil(Math.random() * 100);
        id = Number(id).toString(16);
        let msg = { __id__: id, args: data, __method__: url };
        
        return new Promise((resolve, reject) => {
            let fn = function (err: null | Error, data: any) {
                if (err) {
                    return reject(err);
                }
                return resolve(data);
            }
            this.__ids__[id] = fn;
            self.wepy.sendSocketMessage({
                data: JSON.stringify({
                    __eventKey__: this.__eventKey__,
                    __id__: id,
                    args: data,
                    __method__: url,
                } as ReqParamInterface)
            })
        })
    }
}

export { WepyApi };
export default { WepyApi };